package com.hu.bgp.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

import com.hu.bgp.exceptions.BgpServerException;
import com.hu.bgp.framework.ServerFacade;
import com.hu.bgp.util.ExtensionOnlyFilter;
import com.hu.bgp.util.JarClassLoader;
import com.hu.bgp.util.JarUtil;

/**
 * Verantwoordlijk voor het laden van gametypes uit 'bar'-archives.
 * 
 * @author ejvos
 */
public class BarLoader
{
	private JarClassLoader classLoader = new JarClassLoader();
	static
	{
		// ejvos: dit is handig als je alle klassen in dezelfde classloader wilt
		// hebben
		// maar wij gebruiken alleen de interface naar de geladen klasse dus
		// niet nodig
		// WebAppContext webapp = new WebAppContext();
		// webapp.setClassLoader(classLoader);
	}

	public BarLoader()
	{
	}

	public boolean isValid(File barArchive)
	{
		// TODO Check if the bar file is valid do not load yet...
		return true;
	}

	public void loadGameType(GameType game)
	{

		String barExtractPath = game.getExtractPath();
		String alias = game.getAlias();
		// extract it
		File barExtractDir = new File(barExtractPath + File.separator + alias);
		if (!barExtractDir.exists())
		{
			barExtractDir.mkdirs();
		}
		JarUtil.extract(game.getSourceArchive(), barExtractDir);

		// read bar configuration
		File barConfigFile = new File(barExtractDir.getAbsolutePath() + File.separator + game.getBarConfigFilename());
		Properties p = new Properties();
		String displayName = null;
		String description = null;
		String mainClassFullName = null;
		try
		{
			FileInputStream fis = new FileInputStream(barConfigFile);
			p.load(fis);
			try
			{
				fis.close();
			}
			catch (IOException e)
			{
				// ignored
			}
			displayName = p.getProperty("displayname");
			description = p.getProperty("description");
			mainClassFullName = p.getProperty("serverclass");
		}
		catch (FileNotFoundException e)
		{
			throw new BgpServerException("Could not load config, skipping bar file.");
		}
		catch (IOException e)
		{
			throw new BgpServerException("Could not load config, skipping bar file.");
		}

		// search class file
		Class<? extends ServerFacade> serverClass = null;
		for (File barArchiveEntry : barExtractDir.listFiles(new ExtensionOnlyFilter(".class")))
		{
			try
			{
				Class<? extends ServerFacade> loadFromFile = (Class<? extends ServerFacade>) classLoader.loadFromFile(mainClassFullName, barArchiveEntry);
				serverClass = loadFromFile;
			}
			catch (ClassCastException e) {
				// TODO: handle exception
				System.out.println("Could not load a class: " + e.getMessage());
			}
			catch (ClassNotFoundException e)
			{
				System.out.println("Could not load a class: " + e.getMessage());
			}
		}

		// add to the collection
		game.loaded(serverClass, displayName, description);

	}

}
